﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Nonocast.Http {
	internal abstract class CreateChannelRuleBase : CreateChannelRule {
		public CreateChannelRuleBase(SmallHTTPService host) { this.host = host; }
		public abstract bool IsMatch(ServiceRequestHeader header);
		public abstract ServiceChannel Create(ServiceRequestHeader header);
		protected SmallHTTPService host;
	}

	internal class CreateStaticResourceChannelRule : CreateChannelRuleBase {
		public CreateStaticResourceChannelRule(SmallHTTPService host) : base(host) { }

		public override bool IsMatch(ServiceRequestHeader header) {
			return "/favicon.ico" == header.RequestUri.ToLower() || rule.IsMatch(header.RequestUri);
		}

		public override ServiceChannel Create(ServiceRequestHeader header) {
			return new StaticResourceServiceChannel(header);
		}

		private Regex rule = new Regex(@"^/Resources/");
	}

	internal class CreateActionChannelRule : CreateChannelRuleBase {
		public CreateActionChannelRule(SmallHTTPService host) : base(host) { }

		public override bool IsMatch(ServiceRequestHeader header) {
			return "/" == header.RequestUri || rule.IsMatch(header.RequestUri);
		}

		public override ServiceChannel Create(ServiceRequestHeader header) {
			return new ActionServiceChannel(header, host);
		}

		private Regex rule = new Regex(@"^/Action/");
	}

	internal class CreateWebSocketRFC6455ChannelRule : CreateChannelRuleBase {
		public CreateWebSocketRFC6455ChannelRule(SmallHTTPService host) : base(host) { }

		public override bool IsMatch(ServiceRequestHeader header) {
			return header.Properties.ContainsKey("Connection") && header.Properties.ContainsKey("Upgrade") &&
				   header.Properties["Connection"].ToLower().Contains("upgrade") && header.Properties["Upgrade"].ToLower() == "websocket" &&
				   header.Properties.ContainsKey("Sec-WebSocket-Key");
		}

		public override ServiceChannel Create(ServiceRequestHeader header) {
			return new WebSocketRFC6455ServiceChannel(header, host);
		}
	}

	internal class CreateWebSocketDraft76ChannelRule : CreateChannelRuleBase {
		public CreateWebSocketDraft76ChannelRule(SmallHTTPService host) : base(host) { }

		public override bool IsMatch(ServiceRequestHeader header) {
			return header.Properties.ContainsKey("Connection") && header.Properties.ContainsKey("Upgrade") &&
				   header.Properties["Connection"].ToLower() == "upgrade" && header.Properties["Upgrade"].ToLower() == "websocket" &&
				   header.Properties.ContainsKey("Sec-WebSocket-Key1") && header.Properties.ContainsKey("Sec-WebSocket-Key2");
		}

		public override ServiceChannel Create(ServiceRequestHeader header) {
			return new WebSocketDraft76ServiceChannel(header, host);
		}
	}
}
